package com.example.androidproject.online;
import android.content.Context;
import android.util.Log;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Server {
    private static final String TAG = "Server...";
    private final int port;
    private ServerSocket serverSocket;
    private final Context context;
    private MessageListener messageListener;
    private FileListener fileListener;
    private final ExecutorService executorService = Executors.newFixedThreadPool(10); // 线程池处理多个客户端
    private Socket clientSocket;

    public Server(int port, Context context) {
        this.port = port;
        this.context = context;
    }

    public void setListener(MessageListener messageListener,FileListener fileListener) {
        this.messageListener = messageListener;
        this.fileListener = fileListener;
    }

    public void start() throws IOException {
        serverSocket = new ServerSocket(port);
        Log.d(TAG, "Server started on port " + port);
        while (true) {
            // 接受客户端连接
            clientSocket = serverSocket.accept();
            Log.d(TAG, "Client connected:"+clientSocket.getInetAddress());
            // 使用线程池处理新连接
            executorService.submit(() -> handleClientConnection(clientSocket));
        }
    }

    private void handleClientConnection(Socket clientSocket) {
        try  {
            DataInputStream dis = new DataInputStream(clientSocket.getInputStream());
            String message = dis.readUTF(); // 读取头部信息
            if (message.startsWith("FILE_TRANSFER:")) {
                handleFileTransfer(message);
            } else {
                Log.d(TAG, "Received message from client: " + message);
                if (messageListener != null) {
                    messageListener.onMessageReceived(message);
                }
            }
        } catch (IOException e) {
            Log.e(TAG, "Error handling client connection: " + e.getMessage());
        } finally {
            try {
                clientSocket.close();
            } catch (IOException e) {
                Log.e(TAG, "Error closing client socket: " + e.getMessage());
            }
        }
    }

    private void handleFileTransfer(String header) {
        try {
            // 解析文件名
            String fileName = header.substring("FILE_TRANSFER:".length());
            DataInputStream dis = new DataInputStream(clientSocket.getInputStream());
            long fileLength = dis.readLong();

            byte[] buffer = new byte[2 * 1024 * 1024]; // 2MB缓冲区
            File file = new File(context.getCacheDir(), fileName);

            try (FileOutputStream fos = new FileOutputStream(file)) {
                int bytesRead;
                long totalBytesRead = 0;
                while (totalBytesRead < fileLength && (bytesRead = dis.read(buffer)) != -1) {
                    fos.write(buffer, 0, bytesRead);
                    totalBytesRead += bytesRead;
                }
                Log.d(TAG, "File received and written to: " + file.getAbsolutePath());
                fileListener.onFileReceived(fileName);
            }
        } catch (IOException e) {
            Log.e(TAG, "Error handling file transfer: " + e.getMessage());
        }
    }

    public synchronized void sendFile(File file) {
        Log.d(TAG, "Attempting to send file to client: " + file.length());
        try (FileInputStream fis = new FileInputStream(file);
             DataOutputStream dos = new DataOutputStream(clientSocket.getOutputStream())) {
            // 发送文件名
            dos.writeUTF("FILE_TRANSFER:" + file.getName());
            dos.flush();
            // 发送文件长度
            dos.writeLong(file.length());
            dos.flush();
            // 发送文件内容
            byte[] buffer = new byte[2 * 1024 * 1024]; // 2MB缓冲区
            int bytesRead;
            while ((bytesRead = fis.read(buffer)) != -1) {
                dos.write(buffer, 0, bytesRead);
            }
            dos.flush();
            Log.d(TAG, "File sent successfully to client: " + file.getName());
        } catch (IOException e) {
            Log.e(TAG, "Error sending file to client: " + e.getMessage());
        }
    }

    public synchronized void sendMessage(String message) {
        try (DataOutputStream dos = new DataOutputStream(clientSocket.getOutputStream())) {
            dos.writeUTF(message);
            dos.flush();
            Log.d(TAG, "Message sent to client: " + message);
        } catch (IOException e) {
            Log.e(TAG, "Error sending message to client: " + e.getMessage());
        }
    }


    public void stop() {
        try {
            if (serverSocket != null) {
                serverSocket.close();
            }
            executorService.shutdownNow(); // 关闭线程池
        } catch (IOException e) {
            Log.e(TAG, "Error closing server resources: " + e.getMessage());
        }
    }

    public interface MessageListener {
        void onMessageReceived(String message);
    }
    public interface FileListener {
        void onFileReceived(String fileName);
    }
}
